
//
// Project       : ldpc
// Author        : Shekhalev Denis (des00)
// Workfile      : ldpc_parameters.svh s
// Description   : LDPC codec parameters and needed functions
//

  //------------------------------------------------------------------------------------------------------
  // LDPC code parameters matrix parameters :
  // Wimax :
  //          coderate  - 1/2, 2/3B, 3/4A, 5/6, 2/3A, 3/4B
  //          length    - 576 : x+96 : 2304
  //------------------------------------------------------------------------------------------------------

  parameter int pCODE   =    5; // coderate = pCODE[3 : 0]/(pCODE[3 : 0]+1), codetype = pCODE[4]
  parameter int pN      = 2304;

  localparam int pZF    = get_ZF_size(pCODE, pN); // expansion factor

  localparam int pC     = get_H_size(pCODE, 1);
  localparam int pT     = get_H_size(pCODE, 0);

  localparam int cLDPC_NUM  = pT * pZF;
  localparam int cLDPC_DNUM = (pT - pC) * pZF;

  localparam bit cH_IS_EVEN = 0;

  typedef int H_t [pC][pT];

  H_t Hb;

  assign Hb = get_Hb (pCODE);

  //
  // 2D min-sum normalization factors for all coderates
  //  v-step/h-step normalization is cNORM_BY_8_FACTOR[pCODE]/8

  localparam int cNORM_FACTOR [9] = '{ 7, 7, 7, 7,   // [0...3]
                                       7, 7, 7, 7,   // [4...7]
                                       6 };          // [8]

  //
  // code constants to use instead of digits
  typedef enum bit [3 : 0] {
    cCODE_1by2  = 4'd1,
    //
    cCODE_2by3A = 4'd10,
    cCODE_2by3B = 4'd2,
    //
    cCODE_3by4A = 4'd3,
    cCODE_3by4B = 4'd11,
    //
    cCODE_5by6  = 4'd5
  } ldpc_code_t;

  //------------------------------------------------------------------------------------------------------
  // useful functions
  //------------------------------------------------------------------------------------------------------

  function automatic int get_ZF_size (input int code, int num);
    get_ZF_size = num/24;
  endfunction

  function automatic int get_H_size (input int code, input bit c_nt_sel);
    case (code)
      1   : get_H_size = c_nt_sel ? 12 : 24;
      //
      2   : get_H_size = c_nt_sel ?  8 : 24;
      10  : get_H_size = c_nt_sel ?  8 : 24;
      //
      3   : get_H_size = c_nt_sel ?  6 : 24;
      11  : get_H_size = c_nt_sel ?  6 : 24;
      //
      5   : get_H_size = c_nt_sel ?  4 : 24;
    endcase
  endfunction

  function automatic H_t get_Hb (input int code);
    int Hc_12 [12][24];
    int Hc_23A [8][24];
    int Hc_23B [8][24];
    int Hc_34A [6][24];
    int Hc_34B [6][24];
    int Hc_56  [4][24];
    //
    int tHc   [12][24];
  begin
    // Wimax
    Hc_12 = '{
              '{-1, 94, 73, -1, -1, -1, -1, -1, 55, 83, -1, -1,  7,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
              '{-1, 27, -1, -1, -1, 22, 79,  9, -1, -1, -1, 12, -1,  0,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1},
              '{-1, -1, -1, 24, 22, 81, -1, 33, -1, -1, -1,  0, -1, -1,  0,  0, -1, -1, -1, -1, -1, -1, -1, -1},
              '{61, -1, 47, -1, -1, -1, -1, -1, 65, 25, -1, -1, -1, -1, -1,  0,  0, -1, -1, -1, -1, -1, -1, -1},
              '{-1, -1, 39, -1, -1, -1, 84, -1, -1, 41, 72, -1, -1, -1, -1, -1,  0,  0, -1, -1, -1, -1, -1, -1},
              '{-1, -1, -1, -1, 46, 40, -1, 82, -1, -1, -1, 79,  0, -1, -1, -1, -1,  0,  0, -1, -1, -1, -1, -1},
              '{-1, -1, 95, 53, -1, -1, -1, -1, -1, 14, 18, -1, -1, -1, -1, -1, -1, -1,  0,  0, -1, -1, -1, -1},
              '{-1, 11, 73, -1, -1, -1,  2, -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  0, -1, -1, -1},
              '{12, -1, -1, -1, 83, 24, -1, 43, -1, -1, -1, 51, -1, -1, -1, -1, -1, -1, -1, -1,  0,  0, -1, -1},
              '{-1, -1, -1, -1, -1, 94, -1, 59, -1, -1, 70, 72, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  0, -1},
              '{-1, -1,  7, 65, -1, -1, -1, -1, 39, 49, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  0},
              '{43, -1, -1, -1, -1, 66, -1, 41, -1, -1, -1, 26,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0}};

    Hc_23A = '{
              '{ 3,  0, -1, -1,  2,  0, -1,  3,  7, -1,  1,  1, -1, -1, -1, -1,  1,  0, -1, -1, -1, -1, -1, -1},
              '{-1, -1,  1, -1, 36, -1, -1, 34, 10, -1, -1, 18,  2, -1,  3,  0, -1,  0,  0, -1, -1, -1, -1, -1},
              '{-1, -1, 12,  2, -1, 15, -1, 40, -1,  3, -1, 15, -1,  2, 13, -1, -1, -1,  0,  0, -1, -1, -1, -1},
              '{-1, -1, 19, 24, -1,  3,  0, -1,  6, -1, 17, -1, -1, -1,  8, 39, -1, -1, -1,  0,  0, -1, -1, -1},
              '{20, -1,  6, -1, -1, 10, 29, -1, -1, 28, -1, 14, -1, 38, -1, -1,  0, -1, -1, -1,  0,  0, -1, -1},
              '{-1, -1, 10, -1, 28, 20, -1, -1,  8, -1, 36, -1,  9, -1, 21, 45, -1, -1, -1, -1, -1,  0,  0, -1},
              '{35, 25, -1, 37, -1, 21, -1, -1,  5, -1, -1,  0, -1,  4, 20, -1, -1, -1, -1, -1, -1, -1,  0,  0},
              '{-1,  6,  6, -1, -1, -1,  4, -1, 14, 30, -1,  3, 36, -1, 14, -1,  1, -1, -1, -1, -1, -1, -1,  0}};


    Hc_23B = '{
              '{ 2, -1, 19, -1, 47, -1, 48, -1, 36, -1, 82, -1, 47, -1, 15, -1, 95,  0, -1, -1, -1, -1, -1, -1},
              '{-1, 69, -1, 88, -1, 33, -1,  3, -1, 16, -1, 37, -1, 40, -1, 48, -1,  0,  0, -1, -1, -1, -1, -1},
              '{10, -1, 86, -1, 62, -1, 28, -1, 85, -1, 16, -1, 34, -1, 73, -1, -1, -1,  0,  0, -1, -1, -1, -1},
              '{-1, 28, -1, 32, -1, 81, -1, 27, -1, 88, -1,  5, -1, 56, -1, 37, -1, -1, -1,  0,  0, -1, -1, -1},
              '{23, -1, 29, -1, 15, -1, 30, -1, 66, -1, 24, -1, 50, -1, 62, -1, -1, -1, -1, -1,  0,  0, -1, -1},
              '{-1, 30, -1, 65, -1, 54, -1, 14, -1,  0, -1, 30, -1, 74, -1,  0, -1, -1, -1, -1, -1,  0,  0, -1},
              '{32, -1,  0, -1, 15, -1, 56, -1, 85, -1,  5, -1,  6, -1, 52, -1,  0, -1, -1, -1, -1, -1,  0,  0},
              '{-1,  0, -1, 47, -1, 13, -1, 61, -1, 84, -1, 55, -1, 78, -1, 41, 95, -1, -1, -1, -1, -1, -1,  0}};

    Hc_34A = '{
              '{ 6, 38,  3, 93, -1, -1, -1, 30, 70, -1, 86, -1, 37, 38,  4, 11, -1, 46, 48,  0, -1, -1, -1, -1},
              '{62, 94, 19, 84, -1, 92, 78, -1, 15, -1, -1, 92, -1, 45, 24, 32, 30, -1, -1,  0,  0, -1, -1, -1},
              '{71, -1, 55, -1, 12, 66, 45, 79, -1, 78, -1, -1, 10, -1, 22, 55, 70, 82, -1, -1,  0,  0, -1, -1},
              '{38, 61, -1, 66,  9, 73, 47, 64, -1, 39, 61, 43, -1, -1, -1, -1, 95, 32,  0, -1, -1,  0,  0, -1},
              '{-1, -1, -1, -1, 32, 52, 55, 80, 95, 22,  6, 51, 24, 90, 44, 20, -1, -1, -1, -1, -1, -1,  0,  0},
              '{-1, 63, 31, 88, 20, -1, -1, -1,  6, 40, 56, 16, 71, 53, -1, -1, 27, 26, 48, -1, -1, -1, -1,  0}};

    Hc_34B = '{
              '{-1, 81, -1, 28, -1, -1, 14, 25, 17, -1, -1, 85, 29, 52, 78, 95, 22, 92,  0,  0, -1, -1, -1, -1},
              '{42, -1, 14, 68, 32, -1, -1, -1, -1, 70, 43, 11, 36, 40, 33, 57, 38, 24, -1,  0,  0, -1, -1, -1},
              '{-1, -1, 20, -1, -1, 63, 39, -1, 70, 67, -1, 38,  4, 72, 47, 29, 60,  5, 80, -1,  0,  0, -1, -1},
              '{64,  2, -1, -1, 63, -1, -1,  3, 51, -1, 81, 15, 94,  9, 85, 36, 14, 19, -1, -1, -1,  0,  0, -1},
              '{-1, 53, 60, 80, -1, 26, 75, -1, -1, -1, -1, 86, 77,  1,  3, 72, 60, 25, -1, -1, -1, -1,  0,  0},
              '{77, -1, -1, -1, 15, 28, -1, 35, -1, 72, 30, 68, 85, 84, 26, 64, 11, 89,  0, -1, -1, -1, -1,  0}};

    Hc_56 = '{
              '{ 1, 25, 55, -1, 47,  4, -1, 91, 84,  8, 86, 52, 82, 33,  5,  0, 36, 20,  4, 77, 80,  0, -1, -1},
              '{-1,  6, -1, 36, 40, 47, 12, 79, 47, -1, 41, 21, 12, 71, 14, 72,  0, 44, 49,  0,  0,  0,  0, -1},
              '{51, 81, 83,  4, 67, -1, 21, -1, 31, 24, 91, 61, 81,  9, 86, 78, 60, 88, 67, 15, -1, -1,  0,  0},
              '{68, -1, 50, 15, -1, 36, 13, 10, 11, 20, 53, 90, 29, 92, 57, 30, 84, 92, 11, 66, 80, -1, -1,  0}};
    //
    for (int c = 0; c < pC; c++) begin
      for (int t = 0; t < pT; t++) begin
        case (code)
          1       : tHc[c][t] = Hc_12 [c][t];
          //
          2       : tHc[c][t] = Hc_23B[c][t];
          10      : tHc[c][t] = Hc_23A[c][t];
          //
          3       : tHc[c][t] = Hc_34A[c][t];
          11      : tHc[c][t] = Hc_34B[c][t];
          //
          5       : tHc[c][t] = Hc_56 [c][t];
        endcase
      end
    end
    //
    for (int c = 0; c < pC; c++) begin
      for (int t = 0; t < pT; t++) begin
        case (code)
          //
          10      : get_Hb[c][t] =  (tHc[c][t] < 0) ? -1 : (tHc[c][t] % pZF);
          //
          default : get_Hb[c][t] =  (tHc[c][t] < 0) ? -1 : (tHc[c][t] * pZF)/96;
        endcase
      end
    end
    //
//  for (int j = 0; j < pC; j++) begin
//    $display("Hb[%0d] = %p", j, get_Hb[j]);
//  end
  end
  endfunction

  function automatic int get_phi_Hb (input int code, plength);
    int phi_Hb_34B [19];
    int phi_idx;
  begin
    // exlusive code 3/4B, (-E*T^-1*B+D)^-1 is not eye matrix
    phi_Hb_34B = '{4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16};
    //
    get_phi_Hb = 0;
    phi_idx    = (plength - 576)/96;
    //
    case (code)
      11 : get_phi_Hb = phi_Hb_34B[phi_idx];
    endcase
  end
  endfunction

